#include "imagewindow.h"
#include "ui_imagewindow.h"

ImageWindow::ImageWindow(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ImageWindow)
{
    ui->setupUi(this);
    m_timer = new QTimer(this);
    // m_timer->singleShot() = true;
    m_timer->stop();
    // connect( m_timer , SIGNAL(timeout()) ,this, SLOT(do_timer_timeout()) );

}

ImageWindow::~ImageWindow()
{
    delete ui;
}

// void setComponents(QString filename,QTcpSocket & tran_socket);
void ImageWindow::setComponents(QString filename,QTcpSocket* tran_socket){

    this->filename = filename;
    this->tran_socket = tran_socket;
    ui->textBrowser_filePath->clear();
    ui->textBrowser_filePath->setPlainText( this->filename );
    image.load( filename );
    QPixmap pixmap = QPixmap::fromImage( image );
    ui->label_pic->setPixmap( pixmap );
    ui->label_pic->setScaledContents(true);

};

void ImageWindow::on_pushButton_clicked()
{
    if( this->filename != "" ){
        int image_wide = image.width();
        int image_height = image.height();
        qDebug()<<image_wide <<"  "<<image_height;

        int targetWidth = 800, targetHeight = 480;

        QImage scaled = image.scaled(targetWidth, targetHeight,
                                     Qt::IgnoreAspectRatio,  // 不保持宽高比
                                     Qt::SmoothTransformation); // 使用平滑变换
        QImage rgb888;
        if (scaled.format() != QImage::Format_RGB888) {
            rgb888 = scaled.convertToFormat(QImage::Format_RGB888);
        } else {
            rgb888 = scaled;
        }
        QPixmap pixmap_reg888 = QPixmap::fromImage( rgb888 );
        qDebug()<<pixmap_reg888.width() <<"  "<<pixmap_reg888.height();
        ui->label_pic->setPixmap( pixmap_reg888 );
        ui->label_pic->setScaledContents(true);
        rgb888.save( this->filename);
        saveRGB888ToTxt(rgb888);

    }
}

void ImageWindow::saveRGB888ToTxt(const QImage &image)
{
    // 确保图像是RGB888格式
    if (image.format() != QImage::Format_RGB888) {
        qWarning() << "图像格式不是RGB888";
        return;
    }

    // 创建TXT文件名（在原文件名基础上添加后缀）
    QFileInfo fileInfo(this->filename);
    QString txtFileName = fileInfo.path() + "/" + fileInfo.completeBaseName() + "_rgb888.txt";

    QFile file(txtFileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qWarning() << "无法创建文件:" << txtFileName;
        return;
    }

    QTextStream out(&file);
    const uchar *data = image.constBits();
    int width = image.width();
    int height = image.height();

    // 写入文件头信息
    out << "# RGB888 Pixel Data\n";
    out << "# Image Size: " << width << "x" << height << "\n";
    out << "# Total Pixels: " << width * height << "\n";
    out << "# Format: R G B (each 0-255 decimal)\n";
    out << "# Data Layout:\n";
    out << "#   Row 0: [R00 G00 B00] [R01 G01 B01] ... [R0(n-1) G0(n-1) B0(n-1)]\n";
    out << "#   Row 1: [R10 G10 B10] [R11 G11 B11] ... [R1(n-1) G1(n-1) B1(n-1)]\n";
    out << "#   ...\n";
    out << "#   Row m-1: [R(m-1)0 G(m-1)0 B(m-1)0] ... [R(m-1)(n-1) G(m-1)(n-1) B(m-1)(n-1)]\n\n";

    // 写入像素数据
    for (int y = 0; y < height; y++) {
        out << "# Row " << y << "\n";
        // 每行最多显示16个像素，避免行过长
        const int pixelsPerLine = 16;
        for (int x = 0; x < width; x++) {
            int offset = (y * width + x) * 3;
            // 每16个像素换行
            if (x > 0 && x % pixelsPerLine == 0) {
                out << "\n";
            }
            // 写入RGB值
            out << QString("%1 %2 %3")
                       .arg(static_cast<int>(data[offset]),     3, 10, QChar(' '))
                       .arg(static_cast<int>(data[offset + 1]), 3, 10, QChar(' '))
                       .arg(static_cast<int>(data[offset + 2]), 3, 10, QChar(' '))
                << " ";
        }
        out << "\n\n";
    }
    file.close();
    qDebug() << "RGB888数据已保存到:" << txtFileName;
    // 显示成功消息
    QMessageBox::information(this, "保存成功",
                             QString("RGB888像素数据已保存到:\n%1\n\n"
                                     "图像尺寸: %2x%3\n"
                                     "总像素数: %4")
                                 .arg(txtFileName)
                                 .arg(width)
                                 .arg(height)
                                 .arg(width * height));

}


// 发送PNG图片的函数
void ImageWindow::sendImage( void ) {
    // 1. 加载图片
    QTcpSocket* socket = this->tran_socket;
    const QString imagePath = this->filename;
    if (socket != nullptr ) {
        qWarning() << "没有TCP连接";
        return;
    }
    QImage image(imagePath);
    if (image.isNull()) {
        qWarning() << "无法加载图片:" << imagePath;
        return;
    }
    // 2. 将图片转换为PNG格式的字节数组
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "PNG");
    buffer.close();

    // 3. 准备协议头
    ImageHeader header;
    header.width = image.width();
    header.height = image.height();
    header.dataSize = imageData.size();

    // 4. 发送协议头
    QByteArray headerData(reinterpret_cast<char*>(&header), sizeof(header));
    qint64 bytesWritten = socket->write(headerData);
    if (bytesWritten != sizeof(header)) {
        qWarning() << "协议头发送失败";
        return;
    }
    socket->waitForBytesWritten(1000);

    // 5. 发送图片数据（分块传输）
    qint64 totalBytes = 0;
    const qint64 chunkSize = 4096;  // 4KB分块
    while (totalBytes < imageData.size()) {
        qint64 bytesToWrite = qMin(chunkSize, imageData.size() - totalBytes);
        qint64 bytesWritten = socket->write(imageData.constData() + totalBytes, bytesToWrite);
        if (bytesWritten == -1) {
            qWarning() << "图片数据发送失败:" << socket->errorString();
            return;
        }
        totalBytes += bytesWritten;
        socket->waitForBytesWritten(100);
    }
    qDebug() << "图片发送完成，大小:" << imageData.size() << "字节";
}

void ImageWindow::on_pushButton_tcpTrans_clicked()
{
    const QString imagePath = this->filename;
    QTcpSocket* socket = this->tran_socket;
    if( socket== nullptr  ){
        qWarning() << "没有TCP连接";
        QMessageBox::information(this, "error",QString("没有TCP连接"));
        return;
    }
    QImage image(imagePath);
    if (image.isNull()) {
        qWarning() << "无法加载图片:" << imagePath;
        return;
    }
    socket->write("AT+PICSTART");

    socket->waitForBytesWritten(1000); 
    if(waitForAck(socket,   1000 ,  "AT-PICSTART")){
        qDebug()<<"got ack";
    }
    else{
        qDebug()<<"do not got ack";
        return;
    }

    // 2. 将图片转换为PNG格式的字节数组
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "PNG");
    buffer.close();


    // 3. 准备协议头  10bit数据
    ImageHeader header;
    header.width = image.width();
    header.height = image.height();
    header.dataSize = imageData.size();
    // 4. 发送协议头
    qDebug() << sizeof(header);
    QByteArray headerData(reinterpret_cast<char*>(&header), sizeof(header));
    // qDebug() <<"headerData.size() is"<<headerData.size();
    // for( int i=0;i<headerData.size();i++ ){
    //     qDebug() <<
    //            QString("%1 ").arg(static_cast<quint8>( headerData.at(i) ), 2, 16, QChar('0')).toUpper();
    // }

    qint64 bytesWritten = socket->write(headerData);
    if (bytesWritten != sizeof(header)) {
        qWarning() << "协议头发送失败";
        return;
    }
    socket->waitForBytesWritten(1000);
    qDebug()<< QString("send num is %1").arg(bytesWritten) ;
    if(waitForAck(socket,   1000 ,  "AT-PICSTART_GOT_HEADER")){
        qDebug()<<"got HEADER ack";
    }
    else{
        qDebug()<<"do not got HEADER ack";
        return;
    }


    int cnt  = 0;
    // 5. 发送图片数据（分块传输）
    qint64 totalBytes = 0;
    const qint64 chunkSize = 2048;  // 2KB分块
    while (totalBytes < imageData.size()) {
        qint64 bytesToWrite = qMin(chunkSize, imageData.size() - totalBytes);
        qint64 bytesWritten = socket->write(imageData.constData() + totalBytes, bytesToWrite);
        if (bytesWritten == -1) {
            qWarning() << "图片数据发送失败:" << socket->errorString();
            return;
        }
        cnt++;
        totalBytes += bytesWritten;
        socket->waitForBytesWritten(1000);
        if(waitForAck(socket,   5000 ,  "AT-PICSTART_GOT_HEADER_index"  )){
            qDebug()<<"got PICSTART_GOT_HEADER_index ack index is  "<<cnt ;
        }
        else{
            qDebug()<<"do not got AT-PICSTART_GOT_HEADER_index ack";
            return;
        }
        // atk_mw8266d_uart_printf("AT-PICSTART_GOT_HEADER_%d",i);
    }
    qDebug() << "图片发送完成，大小:" << imageData.size() << "字节";
    qDebug() << "cnt is" << cnt;


}





// void ImageWindow::do_timer_timeout(void){

//     m_timer->stop();
//     const QString imagePath = this->filename;
//     QTcpSocket* socket = this->tran_socket;

//     qWarning() << "time out is ok:" ;
//     ImageHeader header;
//     QFile imageFile(imagePath);
//     QByteArray imageData = imageFile.readAll();
//     header.width = qToBigEndian(static_cast<uint32_t>(image.width())); // 转换为大端序
//     header.height = qToBigEndian(static_cast<uint32_t>(image.height()));
//     header.dataSize = qToBigEndian(static_cast<uint32_t>(imageData.size()));
//     header.checksum = qToBigEndian(qChecksum(imageData.constData(), imageData.size()));

//     const char* headerPtr = reinterpret_cast<const char*>(&header);
//     qDebug() << "图片发送完成，大小:" << sizeof(header) << "字节";
//     qDebug() << headerPtr[0]<<" "<<headerPtr[1];
//     qint64 headerSent = socket->write(headerPtr, sizeof(ImageHeader));
//     if (headerSent != sizeof(ImageHeader)) {
//         qWarning() << "协议头发送失败";
//         return;
//     }
//     qDebug() <<headerPtr;

// };


// 等待ACK的辅助函数
bool ImageWindow::waitForAck(QTcpSocket* socket, int timeoutMs ,QString ACK ) {

    int ACK_size = ACK.size();
    while (socket->bytesAvailable() < ACK_size) { // 最小帧大小
        if (!socket->waitForReadyRead(timeoutMs)) {
            return false; // 超时
        }
    }
    // 验证ACK帧
    QByteArray frame = socket->read(ACK_size); // 读取最小帧
    if (frame.size() < ACK_size) return false;
    QString recv_str = QString::fromLocal8Bit(frame);  // 本地编码
    return recv_str == ACK;
}
